/**
 * Copyright (c) 2016-2018  ghbank.com.cn Corporation Limited .
 * All Rights Reserved
 * This software is the confidential and proprietary information of Ghbank Company
 * You shall not disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into with ghbank.com.cn
 */
package com.subnew.apm.extension;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author JoseanLuo
 * @date 2017/11/2
 * @email joseanluo@gmail.com
 */
public class ExtensionLoader<T> {

    //【局部】扩展点Loader缓存，一个SPI扩展点对应一个ExtensionLoader
    private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<Class<?>, ExtensionLoader<?>>();

    //【局部】扩展点类型
    private final Class<?> type;
    //【局部】扩展点工厂类
    private final ExtensionFactory objectFactory;

    private ExtensionLoader(Class<?> type) {
        this.type = type;
        //TODO  ExtensionFactory扩展点自己为空，其它取adaptive
        objectFactory = null;
    }

    /**
     * 根据扩展点类型获取ExtensionLoader
     */
    public static <T>ExtensionLoader<T> getExtensionLoader(Class<?> type){
        //不能为空
        if(null==type){
            throw new IllegalArgumentException("Extension type == null");
        }
        //必须是接口
        if(!type.isInterface()) {
            throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
        }
        //必须有SPI注解
        if(!type.isAnnotationPresent(SPI.class)){
            throw new IllegalArgumentException("Extension type(" + type + ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
        }

        ExtensionLoader<T> extensionLoader= (ExtensionLoader<T>)EXTENSION_LOADERS.get(type);

        //为空时初始化
        if(null==extensionLoader){
            EXTENSION_LOADERS.putIfAbsent(type,new ExtensionLoader<T>(type));
            extensionLoader= (ExtensionLoader<T>)EXTENSION_LOADERS.get(type);
        }

        return extensionLoader;
    }


}
